home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_std / fixed_array.e < prev    next >
Text File  |  2000-03-25  |  8KB  |  308 lines

  1. -- This file is  free  software, which  comes  along  with  SmallEiffel. This
  2. -- software  is  distributed  in the hope that it will be useful, but WITHOUT 
  3. -- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
  4. -- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
  5. -- this header is kept unaltered, and a notification of the changes is added.
  6. -- You  are  allowed  to  redistribute  it and sell it, alone or as a part of 
  7. -- another product.
  8. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  9. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  10. --                       http://SmallEiffel.loria.fr
  11. --
  12. class FIXED_ARRAY[E]
  13.    --
  14.    -- Resizable, fixed lower bound array.
  15.    -- Unlike ARRAY, the `lower' bound of a FIXED_ARRAY is frozen 
  16.    -- to 0. Thus, some memory is saved and looping toward `lower'
  17.    -- bound (which is 0) run a little bit faster.
  18.    --
  19.  
  20. inherit ARRAYED_COLLECTION[E];
  21.  
  22. creation 
  23.    make, with_capacity, from_collection
  24.  
  25. feature
  26.  
  27.    lower: INTEGER is 0;
  28.          -- Frozen lower bound.
  29.    
  30. feature -- Creation and modification :
  31.    
  32.    make(new_count: INTEGER) is
  33.          -- Make array with range [0 .. `new_count' - 1]. 
  34.          -- When `new_count' = 0 the array is empty.
  35.       require
  36.          new_count >= 0
  37.       do
  38.          if new_count = 0 then
  39.             upper := -1;
  40.          elseif capacity = 0 then
  41.             storage := storage.calloc(new_count);
  42.             capacity := new_count;
  43.             upper := new_count - 1;
  44.          elseif capacity < new_count then
  45.             storage := storage.calloc(new_count);
  46.             capacity := new_count;
  47.             upper := new_count - 1;
  48.          else
  49.             upper := new_count - 1;
  50.             clear_all;
  51.          end;
  52.       ensure
  53.          count = new_count;
  54.          capacity >= old capacity;
  55.          all_default
  56.       end;
  57.  
  58.    with_capacity(needed_capacity: INTEGER) is
  59.          -- Create an empty array with at least `needed_capacity'.
  60.       require
  61.      needed_capacity >= 0
  62.       do
  63.          if capacity < needed_capacity then
  64.             storage := storage.calloc(needed_capacity);
  65.             capacity := needed_capacity;
  66.          end;
  67.          upper := -1;
  68.       ensure
  69.          capacity >= needed_capacity;
  70.          is_empty
  71.       end;
  72.  
  73. feature -- Modification :
  74.  
  75.    resize(new_count: INTEGER) is
  76.          -- Resize the array. When `new_count' is greater than
  77.          -- `count', new positions are initialized with appropriate 
  78.          -- default values.
  79.       require
  80.          new_count >= 0
  81.       local
  82.          new_capacity, i: INTEGER;
  83.          elt_default: like item;
  84.       do
  85.          if new_count <= count then
  86.             upper := new_count - 1;
  87.          else
  88.             new_capacity := new_count;
  89.             if capacity < new_capacity then
  90.                if capacity = 0 then
  91.                   storage := storage.calloc(new_capacity);
  92.                else
  93.                   storage := storage.realloc(capacity,new_capacity);
  94.                end;
  95.                capacity := new_capacity;
  96.             end;
  97.             from
  98.                new_capacity := upper;
  99.                upper := new_count - 1;
  100.                i := upper;
  101.             until
  102.                i = new_capacity
  103.             loop
  104.                put(elt_default,i);
  105.                i := i - 1;
  106.             end;
  107.          end;
  108.       ensure
  109.          count = new_count;
  110.          capacity >= old capacity
  111.       end;
  112.  
  113. feature -- Implementation of deferred :
  114.  
  115.    is_empty: BOOLEAN is
  116.       do
  117.          Result := upper < 0;
  118.       end;
  119.  
  120.    item, infix "@" (index: INTEGER): E is
  121.       do
  122.          Result := storage.item(index);
  123.       end;
  124.    
  125.    put(element: E; index: INTEGER) is
  126.       do
  127.          storage.put(element,index);
  128.       end;
  129.  
  130.    add_first(element: like item) is
  131.       do
  132.          add_last(element);
  133.          if upper = 0 then
  134.          elseif upper = 1 then
  135.             swap(0,1);
  136.          else
  137.             move(0,upper - 1,1);
  138.             put(element,0);
  139.          end;
  140.       end;
  141.  
  142.    add_last(element: like item) is
  143.       local
  144.          new_capacity: INTEGER;
  145.       do
  146.          if upper + 1 <= capacity - 1 then
  147.             upper := upper + 1;
  148.          elseif capacity = 0 then
  149.             storage := storage.calloc(2);
  150.             capacity := 2;
  151.             upper := 0
  152.          else
  153.             new_capacity := 2 * capacity;
  154.             storage := storage.realloc(capacity,new_capacity);
  155.             capacity := new_capacity;
  156.             upper := upper + 1;
  157.          end;
  158.          put(element,upper);
  159.       end;
  160.  
  161.    count: INTEGER is
  162.       do
  163.          Result := upper + 1;
  164.       end;
  165.  
  166.    clear is
  167.       do
  168.          upper := -1;
  169.       ensure then
  170.          capacity = old capacity
  171.       end;
  172.  
  173.    copy(other: like Current) is
  174.          -- Copy `other' onto Current.
  175.       local
  176.          other_upper, new_capacity: INTEGER;
  177.       do
  178.          other_upper := other.upper;
  179.          if other_upper >= 0 then
  180.             new_capacity := other_upper + 1;
  181.             if capacity < new_capacity then
  182.                capacity := new_capacity;
  183.                storage := storage.calloc(new_capacity);
  184.             elseif capacity > 0 then
  185.                storage.clear_all(capacity - 1);
  186.             end;
  187.             storage.copy_from(other.storage,other_upper);
  188.          elseif capacity > 0 then
  189.             storage.clear_all(capacity - 1);
  190.          end;
  191.          upper := other_upper;
  192.       end;
  193.  
  194.    set_all_with(v: like item) is
  195.       do
  196.          storage.set_all_with(v,upper);
  197.       end;
  198.  
  199.    from_collection(model: COLLECTION[like item]) is
  200.       local
  201.          i1, i2, up: INTEGER;
  202.       do
  203.          from
  204.             with_capacity(model.count);
  205.             upper := model.count - 1;
  206.             i1 := 0;
  207.             i2 := model.lower;
  208.             up := model.upper;
  209.          until
  210.             i2 > up 
  211.          loop
  212.             put(model.item(i2),i1);
  213.             i1 := i1 + 1;
  214.             i2 := i2 + 1;
  215.          end;
  216.       end;
  217.    
  218.    is_equal(other: like Current): BOOLEAN is
  219.       do
  220.          if Current = other then
  221.             Result := true;
  222.          elseif upper = other.upper then
  223.             Result := storage.fast_memcmp(other.storage,upper + 1);
  224.          end;
  225.       end;
  226.  
  227.    is_equal_map(other: like Current): BOOLEAN is
  228.       do
  229.          if Current = other then
  230.             Result := true;
  231.          elseif upper = other.upper then
  232.             Result := storage.memcmp(other.storage,upper + 1);
  233.          end;
  234.       end;
  235.  
  236.    all_default: BOOLEAN is
  237.       do
  238.          Result := storage.all_default(upper);
  239.       end;
  240.  
  241.    nb_occurrences(element: like item): INTEGER is
  242.       do
  243.          Result := storage.nb_occurrences(element,upper);
  244.       end;
  245.       
  246.    fast_nb_occurrences(element: E): INTEGER is
  247.       do
  248.          Result := storage.fast_nb_occurrences(element,upper);
  249.       end;
  250.  
  251.    index_of(element: like item): INTEGER is
  252.       do
  253.          Result := storage.index_of(element,upper);
  254.       end;
  255.  
  256.    fast_index_of(element: like item): INTEGER is
  257.       do
  258.          Result := storage.fast_index_of(element,upper);
  259.       end;
  260.  
  261.    subarray, slice(min, max: INTEGER): like Current is
  262.       do
  263.      !!Result.make(max - min + 1);
  264.      Result.storage.copy_slice(0,storage,min, max);
  265.       end;
  266.  
  267.    force(element: E; index: INTEGER) is
  268.       do
  269.          if index <= upper then
  270.             put(element,index);
  271.          elseif index = upper + 1 then
  272.             add_last(element);
  273.          else
  274.             resize(index + 1);
  275.             put(element,index);
  276.          end;
  277.       end;
  278.          
  279.    remove_first is
  280.       local
  281.          dummy: like storage;
  282.       do
  283.          if upper = 0 then
  284.             storage := dummy;
  285.             capacity := 0;
  286.             upper := -1;
  287.          else
  288.             storage.remove_first(upper);
  289.             upper := upper - 1;
  290.          end;
  291.       ensure then
  292.          lower = old lower
  293.       end;
  294.  
  295.    remove(index: INTEGER) is
  296.       do
  297.          storage.remove(index,upper);
  298.          upper := upper - 1;
  299.       end;
  300.    
  301.    get_new_iterator: ITERATOR[E] is
  302.       do
  303.          !ITERATOR_ON_COLLECTION[E]!Result.make(Current);
  304.       end;
  305.  
  306. end -- FIXED_ARRAY[E]
  307.  
  308.